home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / source / xdme_1.84_src.lha / XDME / Src / Var / Flags.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-01  |  5.1 KB  |  226 lines

  1. /******************************************************************************
  2.  
  3.     MODUL
  4.     flags.c
  5.  
  6.     DESCRIPTION
  7.     lowlevel flags-support for DME/XDME
  8.  
  9.     NOTES
  10.     is used by vars.c
  11.  
  12.     BUGS
  13.     <none known>
  14.  
  15.     TODO
  16.     -/-
  17.  
  18.     EXAMPLES
  19.     -/-
  20.  
  21.     SEE ALSO
  22.     vars.c
  23.  
  24.     INDEX
  25.  
  26.     HISTORY
  27.     09-11-92 b_noll created
  28.     15-08-93 b_noll updated
  29.  
  30. ******************************************************************************/
  31.  
  32. /*
  33. **  (C)Copyright 1992 by Bernd Noll for null/zero-soft
  34. **  All Rights Reserved
  35. **
  36. **  RCS Header: $Id: Flags.c 1.2 1994/09/20 11:14:01 b_noll Exp b_noll $
  37. **
  38. **  Basic Functions to work with (arrays of) DME-Flags
  39. **  (both Local and Global Flags use these functions)
  40. **
  41. **  Put together to start a little bit of modularisation
  42. **  in the sources.
  43. */
  44.  
  45. /**************************************
  46.         Includes
  47. **************************************/
  48. #include "defs.h"
  49.  
  50.  
  51. /**************************************
  52.         Globale Exports
  53. **************************************/
  54. Prototype int     test_arg  (char*, int);
  55. Prototype char * GetFlag   (char*, char*, int, char*);
  56. Prototype char     SetFlag   (char*, char*, char*, int, char*);
  57. Prototype int     IsFlagSet (char*, int, int);
  58.  
  59.  
  60. /**************************************
  61.       Interne Defines & Strukturen
  62. **************************************/
  63. static const UBYTE bit[8] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
  64.  
  65.  
  66. /*
  67.  *  test_arg  (previous toggler)
  68.  *
  69.  *  simple hack do be used if you wanna implement
  70.  *  a function which can regognize on/off/toggle for
  71.  *  a BOOL (boolean) variable
  72.  *  args: 1 == TRUE == set == on | 0 == FALSE == reset == off | toggle == switch
  73.  */
  74.  
  75. #define TA_HSH(x,y) ((x & 223) | ((y & 223) << 8))
  76.  
  77. int test_arg (char * str, int bool)
  78. {
  79.  
  80.     if (!str)
  81.     abort (bool);
  82.  
  83.     switch (TA_HSH(str[0], str[1]))
  84.     {
  85.     case TA_HSH('r','e'): /* reset */
  86.     case TA_HSH('0', 0 ): /* 0 */
  87.     case TA_HSH('f','a'): /* false */
  88.     case TA_HSH('o','f'): /* off */
  89.     return (0);
  90.     case TA_HSH('s','e'): /* set */
  91.     case TA_HSH('1', 0 ): /* 1 */
  92.     case TA_HSH('t','r'): /* true */
  93.     case TA_HSH('o','n'): /* on */
  94.     return (1);
  95.     case TA_HSH('t','o'): /* toggle */
  96.     case TA_HSH('s','w'): /* switch  */
  97.     return (!bool);
  98.     default:
  99. //DEFMESSAGE( _FLAG_invalid_value, "test_arg:\n'%s' is not a valid\nvalue for flags!" )
  100.     /* error ( _FLAG_invalid_value, str); */
  101.     abort (bool);
  102.     } /* switch */
  103. } /* test_arg */
  104.  
  105.  
  106.  
  107. int IsFlagSet (char * toggles, int number, int max)
  108. {
  109.     if (number < 0 || number >= max)
  110.     {
  111. //DEFMESSAGE( _FLAG_flagnumber_exceeds_limit, "IsFlagSet:\n'%ld' is not in range\nof [0 ..%ld] !" )
  112.     /* error ("_FLAG_flagnumber_exceeds_limit", number, 0, max-1); */
  113.     abort(0);
  114.     }
  115.  
  116.     return((toggles[number/8] & bit[number&7]) ? 1 : 0);
  117. } /* IsFlagSet */
  118.  
  119.  
  120.  
  121.  
  122.  
  123. /* short : get a number for our Get-/Set-Flag */
  124. /* -1 -> super range */
  125. /* -2 -> no number   */
  126. /* -3 -> wrong start */
  127. /* >= 0 -> use it    */
  128.  
  129. static int checknum (char* name, char* identifier, int max)
  130. {
  131.     int num;
  132.  
  133.     num = strlen (identifier);
  134.  
  135.     /* ---- check for a valid name */
  136.  
  137.     if (strncmp (name, identifier, num))
  138.     return (-3);
  139.  
  140.     name += num;
  141.     if (!is_number (name))
  142.     return (-2);
  143.  
  144.     /* ---- check for a valid range */
  145.  
  146.     num = atoi (name);
  147.     if (num >= max || num < 0)
  148.     return (-1);
  149.  
  150.     return (num);
  151. } /* checknum */
  152.  
  153. /*
  154.  * if the string in name matches the format <xy><num>
  155.  *  <xy>  eq identifier
  156.  *  <num> /N in [0..max]
  157.  * then the flag <num> in toggles is set according to value
  158.  */
  159.  
  160. char SetFlag (char * toggles, char * name, char * value, int max, char * identifier)
  161. {
  162.     int num;  /* total bit number -> BYTE number */
  163.     int bn;   /* bit number in BYTE ... */
  164.     int res;  /* set or not */
  165.  
  166.     switch (num = checknum(name, identifier, max))
  167.     {
  168.     case -3:        /* no header-match */
  169.     case -2:        /* header not followed by number */
  170.     return (0);
  171.     case -1:        /* range error */
  172. //DEFMESSAGE( _FLAG_set_range_error, "SetFlag:\nrange error!" )
  173.     /* error (_FLAG_set_range_error); */
  174.     abort (1);
  175.     default:        /* ok */
  176.     bn  = num & 7;
  177.     num = num / 8;
  178.     res = test_arg(value, toggles[num] & bit[bn]);
  179.     toggles[num] = (toggles[num] & ~bit[bn]) | (res ? bit[bn] : 0);  /* shorter: (res * bit[bn]) */
  180.     return(1);
  181.     } /* switch */
  182. } /* SetFlag */
  183.  
  184.  
  185.  
  186. /*
  187.  * if the string in name matches the format <xy><num>
  188.  *  <xy>  eq identifier
  189.  *  <num> /N in [0..max]
  190.  * then a string is allocated and filled according to flag <num> in toggles
  191.  */
  192.  
  193. char * GetFlag (char * toggles, char * name, int max, char * identifier)
  194. {
  195.     int num;
  196.     char* str;
  197.  
  198.     switch (num = checknum(name, identifier, max))
  199.     {
  200.     case -3:        /* no header-match */
  201.     case -2:        /* header not followed by number */
  202.     return (NULL);
  203.     case -1:        /* range error */
  204. //DEFMESSAGE( _FLAG_get_range_error, "GetFlag:\nrange error!" )
  205.     /* error (_FLAG_get_range_error); */
  206.     abort (NULL);
  207.     default:        /* ok */
  208.     if (!(str = malloc(2)))
  209.     {
  210.         nomemory ();
  211.         return NULL;
  212.     } /* if */
  213.  
  214.     str[0] = '0' + IsFlagSet(toggles, num, max);
  215.     str[1] =  0;
  216.  
  217.     return(str);
  218.     } /* switch */
  219. } /* GetFlag */
  220.  
  221.  
  222. /******************************************************************************
  223. *****  ENDE flags.c
  224. ******************************************************************************/
  225.  
  226.